07. Testing Error Handling
L5 P4 A06 Testing Error Handling V3
In this step you'll test your application reacts appropriately when there's an error (such as data being unavailable from the network).
Step 1: Add an error flag to test double
- Open test > data > source > FakeTestRepository.
- Add a boolean flag called
shouldReturnErrorand set it initially tofalse, which means that by default an error is not returned.
FakeTestRepository.kt
private var shouldReturnError = false
- Create a
setReturnErrormethod that changes whether or not the repository should return errors:
FakeTestRepository.kt
fun setReturnError(value: Boolean) {
shouldReturnError = value
}
- Wrap
getTaskandgetTasksinifstatements so that ifshouldReturnErroristrue, the method returnsResult.Error:
FakeTestRepository.kt
override suspend fun getTask(taskId: String, forceUpdate: Boolean): Result<Task> {
if (shouldReturnError) {
return Error(Exception("Test exception"))
}
tasksServiceData[taskId]?.let {
return Success(it)
}
return Error(Exception("Could not find task"))
}
override suspend fun getTasks(forceUpdate: Boolean): Result<List<Task>> {
if (shouldReturnError) {
return Error(Exception("Test exception"))
}
return Success(tasksServiceData.values.toList())
}
Step 2: Write a test for returned Error
In StatisticsViewModel, there are two LiveData booleans (error and empty):
StatisticsViewModel.kt
class StatisticsViewModel(
private val tasksRepository: TasksRepository
) : ViewModel() {
private val tasks: LiveData<Result<List<Task>>> = tasksRepository.observeTasks()
// Other variables...
val error: LiveData<Boolean> = tasks.map { it is Error }
val empty: LiveData<Boolean> = tasks.map { (it as? Success)?.data.isNullOrEmpty() }
// Rest of the code...
}
These represent whether or not tasks loaded properly. If there is an error, error and empty should both be true.
- Open StatisticsViewModelTest.
- Create a new test called
loadStatisticsWhenTasksAreUnavailable_callErrorToDisplay - Call
setReturnErrors()ontasksRepository, setting it totrue. - Call
statisticsViewModel.refresh()to trigger a data load. - Check that
statisticsViewModel.emptyandstatisticsViewModel.errorare bothtrue.
The full code for this test is below:
StatisticsViewModelTest.kt
@Test
fun loadStatisticsWhenTasksAreUnavailable_callErrorToDisplay() {
// Make the repository return errors.
tasksRepository.setReturnError(true)
statisticsViewModel.refresh()
// Then empty and error are true (which triggers an error message to be shown).
assertThat(statisticsViewModel.empty.getOrAwaitValue(), `is`(true))
assertThat(statisticsViewModel.error.getOrAwaitValue(), `is`(true))
}
- Run your test and observe it passing!